/**
 * Copyright (c) 2010-2011 Pierre LABATUT
 *
 * This file is part of multiple-track-player project.
 *
 * multiple-track-player is free software: you can redistribute it and/or modify it
 * under the terms of its license which may be found in the accompanying
 * LICENSE file or <http://code.google.com/p/multiple-track-player/>.
 */
package multitrack.preload;

import java.awt.Component;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import multitrack.annotation.ThreadSafe;

/**
 * Swing panel component that gathers a play control button and several tracks
 * 
 * @author Pierre LABATUT
 */
public class AudioPlayerView extends javax.swing.JPanel {

    static void setSystemLookAndFeel() {
        /**
         * Set the look and feel to mimic the system default one
         */
        try {
            // Set System L&F
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (UnsupportedLookAndFeelException e) {
            // handle exception
        } catch (ClassNotFoundException e) {
            // handle exception
        } catch (InstantiationException e) {
            // handle exception
        } catch (IllegalAccessException e) {
            // handle exception
        }
    }

    /** Creates new form View */
    public AudioPlayerView() {
        initComponents();
    }
    final Timer positionPoll = new Timer("positionPoll");
    MixAudioBuffer mix;
    AudioPlayer player;

    void doSeek(int framePosition) {
        player.seek(framePosition);
    }

    void setPosition(final int positionInFrame) {

        final float frameRate = mix.format().getFrameRate();
        if (frameRate < 0) {
            throw new RuntimeException("Unspecified framerate not supported!");
        }
        final float channels = mix.format().getChannels();
        if (channels < 0) {
            throw new RuntimeException("Unspecified framerate not supported!");
        }
        int positionInSec = (int) ((float) positionInFrame / frameRate);
        int lengthInSec = (int) ((float) mix.samples() / mix.format().getChannels() / frameRate);
        pos.setText(String.format("%1$d.%2$02d/%3$d.%4$02d", positionInSec / 60, positionInSec % 60, lengthInSec / 60, lengthInSec % 60));
        for (Component c : waveFormPanel.getComponents()) {
            ((TrackView) c).updatePlayCursor(positionInFrame);
        }
        repaint();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        waveFormPanel = new javax.swing.JPanel();
        jPanel1 = new javax.swing.JPanel();
        jPanel2 = new javax.swing.JPanel();
        playButton = new ImagePushButton();
        pos = new javax.swing.JLabel();
        jSeparator1 = new javax.swing.JSeparator();

        setLayout(new java.awt.BorderLayout());

        waveFormPanel.setLayout(new javax.swing.BoxLayout(waveFormPanel, javax.swing.BoxLayout.PAGE_AXIS));
        add(waveFormPanel, java.awt.BorderLayout.CENTER);

        jPanel1.setLayout(new javax.swing.BoxLayout(jPanel1, javax.swing.BoxLayout.LINE_AXIS));

        jPanel2.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
        jPanel2.setLayout(new javax.swing.BoxLayout(jPanel2, javax.swing.BoxLayout.PAGE_AXIS));

        playButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/multitrack/preload/gtk-media-play-rtl.png"))); // NOI18N
        playButton.setBorder(null);
        playButton.setBorderPainted(false);
        playButton.setEnabled(false);
        playButton.setSelectedIcon(new javax.swing.ImageIcon(getClass().getResource("/multitrack/preload/gtk-media-pause.png"))); // NOI18N
        playButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                playButtonActionPerformed(evt);
            }
        });
        jPanel2.add(playButton);

        pos.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        pos.setMaximumSize(new java.awt.Dimension(73, 14));
        pos.setMinimumSize(new java.awt.Dimension(73, 14));
        jPanel2.add(pos);

        jPanel1.add(jPanel2);

        jSeparator1.setForeground(new java.awt.Color(204, 204, 204));
        jSeparator1.setOrientation(javax.swing.SwingConstants.VERTICAL);
        jSeparator1.setPreferredSize(new java.awt.Dimension(1, 0));
        jPanel1.add(jSeparator1);

        add(jPanel1, java.awt.BorderLayout.WEST);
    }// </editor-fold>//GEN-END:initComponents

    private void playButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_playButtonActionPerformed
        player.play(playButton.isSelected());
}//GEN-LAST:event_playButtonActionPerformed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JToggleButton playButton;
    private javax.swing.JLabel pos;
    private javax.swing.JPanel waveFormPanel;
    // End of variables declaration//GEN-END:variables

    public void setMix(final MixAudioBuffer mix) {
        if (this.mix != null) {
            throw new IllegalStateException();
        }
        this.mix = mix;
        waveFormPanel.setLayout(new javax.swing.BoxLayout(waveFormPanel, javax.swing.BoxLayout.PAGE_AXIS));
        for (final Track track : mix.tracks) {
            waveFormPanel.add(new TrackView(this, mix, track));
        }
        validate();

    }

    public void setPlayer(final AudioPlayer player) {
        if (this.player != null) {
            throw new IllegalStateException();
        }

        this.player = player;
        player.addView(this);
        playButton.setEnabled(true);
        positionPoll.schedule(new TimerTask() {

            @Override
            public void run() {
                final int position = player.playCursorPosInFrame();
                setPosition(position);
            }
        }, 0, 30);


    }

    @ThreadSafe
    public void notifyPlay() {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                playButton.setSelected(true);

            }
        });
    }

    public @ThreadSafe
    void notifyStop() {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                playButton.setSelected(false);

            }
        });
    }
}
